package ltu.thole;
// Importing all kinds of stuff...
import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

public class ThoLeMaps extends MapActivity {
	
	private MapView mapView;
	private MapController mapController;
	private List<Overlay> mapOverlays;
	private ThoLe_ItemizedOverlay itemizedoverlay;
	private ThoLe_ItemizedOverlay myItemizedoverlay;
	private ArrayList<GeoPoint> geoPoints = new ArrayList<GeoPoint>();
	private GeoPoint point;
	private LocationManager locationManager;
	private LocationListener locationListener;
	private Context context;
	private GeoPoint myLocation = null;
	private OverlayItem myOverlayitem;
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        context = this;
        
        // Creating a new mapView from an already existing one.
        // I don't know why you'll have to do it like this. I hope there is a good reason that I'm not aware of.
        mapView = (MapView)findViewById(R.id.mapview);
        mapView.setBuiltInZoomControls(true);
        mapView.setSatellite(true);
        // Creating a MapController which is used to send commands to the map, for example 'Zoom in'.
        mapController = mapView.getController();
        // Creating a MapOverlay where all the icons will be placed.
        mapOverlays = mapView.getOverlays();
        // Creating two different icons.
        Drawable drawable = this.getResources().getDrawable(R.drawable.map_icon);
        itemizedoverlay = new ThoLe_ItemizedOverlay(drawable, this);
        drawable = this.getResources().getDrawable(R.drawable.my_location_blue);
        myItemizedoverlay = new ThoLe_ItemizedOverlay(drawable, this);
        
        // Creating a location manager and a location listener.
        locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
        locationListener = new LocationListener() {
        	/** Called when a change of location is detected. */
            public void onLocationChanged(Location location) {
            	// Converting the location to Latitude E6 and Longitude E6.
            	int latitude = (int)(location.getLatitude()*1E6);
            	int longitude = (int)(location.getLongitude()*1E6);
            	// Show a short message with the coordinates.
            	Toast.makeText(context, ("onLocationChanged()\nLatidude: " + latitude + "\nLongitude: " + longitude), Toast.LENGTH_SHORT).show();
            	// Creating a new GeoPoint for the current location.
            	myLocation = new GeoPoint(latitude, longitude);
				// Creating an overlay/icon for the new location.
            	myOverlayitem = new OverlayItem(myLocation, "My Location", "Latitude: " + myLocation.getLatitudeE6() + "\nLongitude: " + myLocation.getLongitudeE6());
            	myItemizedoverlay.addOverlay(myOverlayitem);
                mapOverlays.add(myItemizedoverlay);
                // Center the new location in the map.
                mapController.setCenter(myLocation);  
            }
            
            /** Called when the location service status is changed. */
            public void onStatusChanged(String provider, int status, Bundle extras) {
            	Toast.makeText(context, "onStatusChanged()", Toast.LENGTH_SHORT).show();
            }
            
            /** Called when a location service provider is enabled. */
            public void onProviderEnabled(String provider) {
            	Toast.makeText(context, "onProviderEnabled()", Toast.LENGTH_SHORT).show();
            }
            
            /** Called when a location service provider is disabled. */
            public void onProviderDisabled(String provider) {
            	Toast.makeText(context, "onProviderDisabled()", Toast.LENGTH_SHORT).show();
            }
        };
        // Setting a comfortable zoom-level.
        mapController.setZoom(19);
    }
    
    /** Called when user wants to use GPS as location provider. */
    private void useGps() {
    	locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 4000, 1, locationListener);
    	Toast.makeText(context, "Requesting GPS Provider", Toast.LENGTH_SHORT).show();
    }
    
    /** Called when user wants to use the network as location provider. */
    private void useWifi() {
    	locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 4000, 1, locationListener);
    	Toast.makeText(context, "Requesting Network Provider", Toast.LENGTH_SHORT).show();
    }
    
    /** Create GeoPoint from a Location. */
    private void createGeoPoint(Location location) {
    	if (location != null) {
    		createGeoPoint((int)(location.getLatitude()*1E6), (int)(location.getLongitude()*1E6));
    	} else {
    		Toast.makeText(context, "Could not get a location", Toast.LENGTH_SHORT).show();
    	}
    }
    
    /** Create a GeoPoint from Latitude E6 and Longitude E6. */
    private void createGeoPoint(int latitude, int longitude) {
    	point = new GeoPoint(latitude, longitude);
        geoPoints.add(point);
        OverlayItem overlayitem = new OverlayItem(point, ("GeoPoint " + geoPoints.size()), "Latitude: " + point.getLatitudeE6() + "\nLongitude: " + point.getLongitudeE6());
        itemizedoverlay.addOverlay(overlayitem);
        mapOverlays.add(itemizedoverlay);
        mapController.setCenter(point);
        String text = "New GeoPoint created. (" + geoPoints.size() + ")";
        if(geoPoints.size() > 1) {
        	GeoPoint oldPoint = geoPoints.get(geoPoints.size()-2);
        	// Getting the distance between the two points.
        	String distanceResult = Double.toString(DistanceCalculator.getDistanceInMeters(oldPoint, point));
        	text = text + "\nDistance to last GeoPoint:\n" + distanceResult + " meter";
        }
        
        Toast.makeText(this, text, Toast.LENGTH_LONG).show();
    }
    
    /** Enable menu button for this activity */
    @Override public boolean onCreateOptionsMenu(Menu menu) {
    	populateMenu(menu);
    	return super.onCreateOptionsMenu(menu);
    }

    /** Called when a menu button option is selected */
    @Override public boolean onOptionsItemSelected(MenuItem item) {
    	return applyMenuChoice(item) || super.onOptionsItemSelected(item);
    }
    // Creating item ID's
    public static final int Menu1 = Menu.FIRST + 1;
    public static final int Menu2 = Menu.FIRST + 2;
    public static final int Menu3 = Menu.FIRST + 3;
    public static final int Menu4 = Menu.FIRST + 4;
    public static final int Menu5 = Menu.FIRST + 5;
    public static final int Menu6 = Menu.FIRST + 6;

    /** Creating the menu items */
    public void populateMenu(Menu menu) {
      menu.setQwertyMode(true);
      MenuItem item1 = menu.add(0, Menu1, 0, "Satellite Layer On");
      {
        item1.setAlphabeticShortcut('1');
      }
      MenuItem item2 = menu.add(0, Menu2, 1, "Satellite Layer Off");
      {
        item2.setAlphabeticShortcut('2');
      }
      MenuItem item3 = menu.add(0, Menu3, 2, "Use GPS");
      {
        item3.setNumericShortcut('3');
      }
      MenuItem item4 = menu.add(0, Menu4, 3, "Use Network");
      {
        item4.setNumericShortcut('4');
      }
      MenuItem item5 = menu.add(0, Menu5, 4, "Stop Location Listener");
      {
        item5.setNumericShortcut('5');
      }
      MenuItem item6 = menu.add(0, Menu6, 5, "Add GeoPoint");
      {
        item6.setNumericShortcut('6');
      }
    }
    
    /** respond to menu item selection */
    public boolean applyMenuChoice(MenuItem item) {
      switch (item.getItemId()) {
        case Menu1:
        	// Enable satellite-view.
        	mapView.setSatellite(true);
        	return true;
        case Menu2:
        	// Disable satellite-view.
        	mapView.setSatellite(false);
          return true;
        case Menu3:
        	// Use GPS as location provider.
        	useGps();
          return true;
        case Menu4:
        	// Use network as a location provider.
        	useWifi();
            return true;
        case Menu5:
        	// Remove the location listener.
        	locationManager.removeUpdates(locationListener);
        	Toast.makeText(context, "Location Listener Removed", Toast.LENGTH_SHORT).show();
            return true;
        case Menu6:
        	// Create a GeoPoint from the last known location.
        	createGeoPoint(locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER));
            return true;
      }
      return false;
    }

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}
}
